package edu.gyc.producer.consumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//Lock 与synchronize都是阻塞线程，但lock可重入锁可以精确唤醒等待的线程，通过condition
class HiData {
    private int number = 3;
    private Lock lock = new ReentrantLock();
    private Condition a = lock.newCondition();
    private Condition b = lock.newCondition();
    private Condition c = lock.newCondition();

    public void print3() throws Exception {
        lock.lock();

        try {

            //1 判断
            while (number !=3) {
                a.await();
            }
            //2 工作
            for (int i = 0; i < 3; i++) {
                System.out.println("AA");
            }
           //3 通知
            number=6;
            b.signal();


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void print6() throws Exception {
        lock.lock();

        try {
            while (number != 6) {
                b.await();
            }
            for (int i = 0; i < 6; i++) {
                System.out.println("BB");

            }



            number=9;
            c.signal();


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void print9() throws Exception {
        lock.lock();

        try {
            while (number !=9) {
                c.await();
            }
            for (int i = 0; i < 9; i++) {
                System.out.println("CC");

            }

            number=3;
            a.signal();
         } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }


    }
//A线程打印3个后B线程打印6后C线程打印9个，循环10次，用lock的condition精确唤醒线程
public class NextPrintNew {
    public static void main(String[] args) {
        HiData hiData =new HiData();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                try {
                    hiData.print3();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();

            new Thread(()->{
                try {
                    hiData.print6();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();

            new Thread(()->{
                try {
                    hiData.print9();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}